<?php
require_once ( "ajax_module.php" );
require_once ( "utils.php" );

class layout_manager
{
	function layout_manager ( & $dbm )
	{
		$this->dbm = & $dbm;

		$this->css = Array ();
		$this->js  = Array ();
		$this->js_post  = Array ();
		$this->events = Array ();
		$this->dups = Array ();
		$this->post_dups = Array ();
		$this->globals = Array ();

		$this->postloader_events = Array ( );

		$this->doctype =  "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Strict//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd\">";

		// This array will contain JS Functions to be added in the <head> field.
		$this->js_funcs = Array ();

		// This array will contain JS Code to be added in the <head> field.
		$this->js_code = Array ();

		// Local directory for static pages (not in DB)
		$this->pages_dir = "pages";

		// Modules directory
		$this->modules_dir = "modules";

		// Page Title
		$this->page_title = null;

		// Images Root
		$this->img_root = "/"; ///prods/omen";

		// Favicon
		$this->favicon = null;

		$this->send_gzip = "os3phplib/send_gzip.php?fname=";

		$this->add_event ( "load",  "liwe.ajax_url = '" . dirname ( $_SERVER [ 'PHP_SELF' ] ) . "/ajax.php';", true );
	}

	function add_css ( $file_name, $id = false, $medium = false, $gzip = false ) { if ( @$this->dups [ $file_name ] ) return; $this->css [] = Array ( $file_name, $id, $medium, $gzip ); $this->dups [ $file_name ] = 1; }
	function add_js_func  ( $code ) { $this->js_funcs [] = $code; }
	function add_js_code  ( $code ) { $this->js_code [] = $code; }
	function add_global ( $var_name, $value ) { $this->globals [ $var_name ] = $value; }

	function add_js  ( $file_name, $gzip = true, $compressed = false ) 
	{ 
		if ( @$this->dups [ $file_name ] ) return; 

		if ( $compressed ) $file_name = str_replace ( ".js", "_comp.js", $file_name );

		$this->js [] = Array ( $file_name, $gzip ); 
		$this->dups [ $file_name ] = 1; 
	}

	function add_js_post ( $file_name, $check_for, $pri = 9, $cback = "null", $vars = "null",  $gzip = true )
	{
		if ( @ $this->post_dups [ $file_name ] ) return;

		if ( $cback === null ) $cback = "null";

		$this->js_post [] = Array ( "pri" => $pri, "fname" => $file_name, "check_for" => $check_for, "cback" => $cback, "vars" => $vars, "gzip" => $gzip );
		$this->post_dups [ $file_name ] = 1;
	}

	function add_event ( $event_name, $code, $in_head = false )
	{
		@ $ev = & $this->events [ $event_name ];
		if ( ! $ev ) $ev = Array ();

		if ( ! $in_head )
			$ev [] = $code;
		else
			array_splice ( $ev, 0, 0, $code ); 

		$this->events [ $event_name ] = $ev;
	}

	function show ( $page_name, $footer = true )
	{
		$vals = & $this->load_page ( $page_name );

		if ( ! $vals ) 
		{
			util_sys_err ( "ERROR", "Could not load layout: <strong>$page_name</strong>" );
			return;
		}

		if ( $this->page_title == null ) $this->page_title = $vals [ 'title' ];

		$this->header ( $this->page_title );
		print $vals [ 'data' ];

		if ( $footer ) $this->footer ();
	}

	function & load_page ( $page_name, $block_name = false )
	{
		error_log ( "Load Page: {$page_name}" );
		// error_log ( "Load Page: " . $this->pages_dir . "/{$page_name}.html" );

		$vals = "";

		// $vals = & $this->dbm->single_row ( "SELECT data, title FROM layout_data WHERE name='$page_name'", false );

		// if ( ! $vals ) return $vals;

		if ( ! $vals ) $vals = array ( 'data' => '*', 'title' => $page_name );

		if ( $vals [ 'data' ] == '*' ) 
		{
			$pag = util_read_file ( $this->pages_dir . "/{$page_name}.html" );

			$pag = $this->_apply_regex ( $pag, $block_name );

			$vals [ 'data' ] = $this->_parse_data ( $pag );
		} else 
			$vals [ 'data' ] = $this->_parse_data ( $vals [ 'data' ] );

		if ( $this->img_root ) $vals [ 'data' ] = eregi_replace ( "<img src=.gfx", "<img src=\"" . $this->img_root . "/gfx", $vals [ 'data' ] );

		return $vals;
	}

	function & get_template ( $page_name, $block_name = false )
	{
		$res = $this->load_page ( $page_name, $block_name );

		return $res [ 'data' ];
	}

	function _apply_regex ( $pag, $bn )
	{
		$pag = str_replace ( array ( "\n", "\t", "\r" ), "", $pag );

		$pag = preg_replace ( "/.*<body[^>]*>(.*)<\/body>.*/i", "$1", $pag );

		if ( $bn )
		{
			if ( strpos ( $pag, "{{{ BLK: $bn" ) === false )
			{
				$pag = "<strong style=\"color: red\">Could not find: $bn</strong>";
				return $pag;
			}

			$pag = preg_replace ( "/.*<!-- {{{ BLK: $bn -->(.*)<!-- }}} $bn -->(.*)$/Ui", "$1", $pag );
		}

		$pag = preg_replace ( "/<!-- {{{ REP: (?<nome>[^ ]*) (.*) -->.*<!-- }}} \k<nome> -->/U", "$2", $pag );
		$pag = preg_replace ( "/<!--.*-->/U", "", $pag );

		return $pag;
	}

	function header ( $title )
	{
		print $this->doctype. "\n<html>\n<head>\n<title>" . $title . "</title>\n";

		if ( $this->favicon )
			print '<link rel="shortcut icon" href="' . $this->favicon . '" />';

		foreach ( $this->css as $arr )
		{
			$fname 	= $arr [ 0 ];
			$id    	= $arr [ 1 ];
			$medium = $arr [ 2 ];
			$gzip   = $arr [ 3 ];

			if ( $gzip ) $gzip = $this->send_gzip;

			if ( ( $fname [ 0 ] == '/' ) || ( filesys_exists ( $fname ) ) ) 
			{
				print "<link href=\"{$gzip}{$fname}\" type=\"text/css\" rel=\"stylesheet\"";
				if ( $id ) print " id=\"$id\"";
				if ( $medium ) print " media=\"$medium\"";
				print "/>\n";
			}
		}

		foreach ( $this->js as $arr )
		{
			list ( $fname, $gzip ) = $arr;
			if ( $gzip ) $gzip = $this->send_gzip;

			if ( ( $fname [ 0 ] == '/' ) || ( filesys_exists ( $fname ) ) ) 
					print "<script type=\"text/javascript\" src=\"{$gzip}{$fname}\"></script>\n";
		}

		if ( sizeof ( $this->globals ) )
		{
			print "<script type=\"text/javascript\" language=\"javascript\">// <![CDATA[\n";
			foreach ( $this->globals as $name => $val ) print "var $name = $val;\n";
			
			print "// ]]></script>\n";
		}
	

		if ( sizeof ( $this->js_code ) )
		{
			print "<script type=\"text/javascript\" language=\"javascript\">// <![CDATA[";
			foreach ( $this->js_code as $code ) print "$code\n";
			print "// ]]></script>\n";
		}

		$events = '';

		if ( sizeof ( $this->js_post ) ) $this->add_event ( "load", "layman_post_loader()", true );

		if ( sizeof ( $this->events ) )
		{
			print '<script type="text/javascript"> // <![CDATA[' . "\n";
			foreach ( $this->events as $evt_name => $data )
			{
				$events .= " on{$evt_name}=\"layman_{$evt_name}()\"";
				print "function layman_{$evt_name} ()\n";
				print "{\n";

				foreach ( $data as $code )
					print $code . ";\n";

				print "}\n";
			}

			if ( sizeof ( $this->js_post ) )
			{
				print "function layman_post_loader ()\n{";
				foreach ( $this->js_post as $js_req => $data )
				{
					if ( $data [ 'gzip' ] ) $gzip = $this->send_gzip;
					else $gzip = '';

					print "liwe.postload.add ( '{$gzip}{$data['fname']}','{$data['check_for']}',{$data['pri']},{$data['cback']},{$data['vars']});\n";
				}

				foreach ( $this->postloader_events as $k => $v )
				{
					if ( ! $v ) continue;
					print "liwe.postload.events [ '$k' ] = $v;";
				}

				print "liwe.postload.load ();\n";
				print "}";
			}
			print "// ]]></script>\n";
		}

		print "</head>\n<body $events>";
	}

	function footer ()
	{
		print "</body>\n</html>";
	}

	function & _split_str ( $sub )
	{
		$res = array ();

		$cmds = preg_split ( '/\s(?=(?:[^"\']*["\'][^"\']*["\'])*[^"\']*\z)/', $sub, -1, PREG_SPLIT_NO_EMPTY );

		foreach ( $cmds as $c )
		{
			if ( ( $c [ 0 ] == '"' ) || ( $c [ 0 ] == "'" ) )
			$c = substr ( $c, 1, -1 );

			$res [] = $c;
		}

		return $res;
	}

	function _parse_data ( $data )
	{
		$res = '';

		$start_pos = 0;

		while ( ( $x = strpos ( $data, "<?fab", $start_pos ) ) !== false )
		{
			$res .= substr ( $data, $start_pos, $x - $start_pos );
			$start_pos = $x + 5;

			$x = strpos ( $data, "?>", $start_pos );
			if ( $x == false )
			{
				util_sys_err ( "ERROR", "Missing end tag in template. Last valid pos: $start_pos" );
				break;
			}

			$sub = substr ( $data, $start_pos, $x - $start_pos );
			$cmds = $this->_split_str ( $sub );

			// error_log ( "Parse: " . $cmds [ 0 ] . " - " . $cmds [ 1 ] );
			$res .= $this->execute ( & $cmds );
			$start_pos = $x + 2;
		}

		$res .= substr ( $data, $start_pos );

		return $res;
	}



	function & execute ( & $cmds )
	{
		$am = new ajax_module ( & $this->dbm, "modules", & $this );
		$res = & $am->exec ( $cmds [ 0 ], @$cmds [ 1 ], & $cmds );

		if ( $res === null ) 
			@ $res = util_sys_err ( "ERROR", "Could not load: <strong>{$cmds [ 0 ]}</strong> for <em>{$cmds [ 1 ]}</em>", true );

		return $res;
	}

	function postloader_event_add ( $event_name, $code )
	{
		$this->postloader_events [ $event_name ] = $code;
	}
}
?>
